﻿using bleCore;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Windows.Devices.Bluetooth.GenericAttributeProfile;

namespace temperatureGui
{
    public partial class TemperatureIndicator : Form
    {
        const int DISPLAY_MIN = 5;
        DateTime startTime = DateTime.Now;
        public TemperatureIndicator()
        {
            InitializeComponent();
            DeviceManager.DeviceDiscovery += DeviceManager_DeviceDiscovery;
            DeviceManager.BleDataReceived += DeviceManager_BleDataReceived;
            Monitor.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
        }
        List<ClientConfig> clientConfig;
        private void MakeChartSeries(string id)
        {
            var s = Monitor.Series.FindByName(id);
            if (s == null) s = Monitor.Series.Add(id);
            if (!s.Enabled) s.Enabled = true;
            s.ChartType = SeriesChartType.Spline;
            s.XValueType = ChartValueType.Time;
            s.YValueType = ChartValueType.UInt32;
        }
        private List<ClientConfig> setConfig()
        {
            clientConfig= new List<ClientConfig>();
            var mac_list = File.ReadAllLines("./mac.txt");
            foreach (var mac in mac_list)
            {
                var c = mac.Trim();
                if (c.StartsWith("#")) continue;
                if (c == "") continue;
                var ca = c.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                clientConfig.Add(new ClientConfig()
                {
                    MAC = ca[0],
                    NAME = ca.Length > 1 ? ca[1] : ca[0],
                    GATT_LIST = new string[] { Consts.GATT_TEMPERATURE }
                });
            }
            return clientConfig;
        }
        private void DeviceManager_BleDataReceived(MyBleDevice device, GattCharacteristic sender, byte[] data)
        {
            if (sender.Uuid == new Guid(Consts.GATT_TEMPERATURE))
            {
                Logger.LogMsg("从{0}中接收到数据{1}", device.DEVICE_ID, data[0]);
                this.Invoke((EventHandler)delegate
                {
                    var msg = new TemperatureMsg(device.DEVICE_ID, DateTime.Now, data[0]);
                    draw(msg);
                });
            }
        }
        private void draw(TemperatureMsg msg) 
        {
            var now = DateTime.Now;
            var now_as_dbl = now.ToOADate();
            LiteDb.InsertMsg(msg);
            var s = Monitor.Series.FindByName(Id2Name(msg.Device));
            var xAxisPoint = now.AddMinutes(-DISPLAY_MIN);
            if (xAxisPoint < startTime) xAxisPoint = startTime;
            var chartAreas = Monitor.ChartAreas[0];
            chartAreas.AxisX.Minimum = xAxisPoint.ToOADate();
            chartAreas.AxisX.Maximum = xAxisPoint.AddMinutes(DISPLAY_MIN).ToOADate();
            s.Points.AddXY(now_as_dbl, msg.Degree);
            var removes = s.Points.Where(r => r.XValue < chartAreas.AxisX.Minimum).ToList();
            if (removes.Count > 100)
            {
                foreach (var r in removes)
                {
                    s.Points.Remove(r);
                    r.Dispose();
                }
                Logger.LogSys("已移除{0}个点位", removes.Count());
                Logger.LogSys("device={0}的点位数={1}", msg.Device, s.Points.Count);

            }
        }

        private void DeviceManager_DeviceDiscovery(MyBleDevice client)
        {

            client.ConnectLost += Client_ConnectLost;
            this.Invoke((EventHandler)delegate
            {
                MakeChartSeries(Id2Name(client.DEVICE_ID));
            });
            foreach (var notifier in client.Notifier)
            {
                client.EnableGattReceive(notifier.Uuid.ToString());
            }
        }

        private void Client_ConnectLost(MyBleDevice device)
        {
            var s = Monitor.Series.FindByName(Id2Name(device.DEVICE_ID));
            this.Invoke((EventHandler)delegate
            {
                s.Enabled = false;
            });
        }

        private string Id2Name(string id)
        {
            var cfg = clientConfig.FirstOrDefault(r => id.Contains(r.MAC));
            if (cfg != null)
                return cfg.NAME;
            return "未知监测站";
        }
        private void TemperatureIndicator_Load(object sender, EventArgs e)
        {
            Thread t = new Thread(() =>
            {
                DeviceManager.Discovery(setConfig());
            });
            t.Start();
        }

    }
}
